﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Sio.Mdm.Entities;
using Sio.Mdm.Types;
using System.Linq.Expressions;

namespace Sio.Mdm.BL.Base
{
    public abstract class BaseBLGeneric<T> : BaseBL, IBaseService<T> where T: class, IEntity
    {
        #region Construction
        public BaseBLGeneric()
            : this(null)
        {
        }

        public BaseBLGeneric(string connectionString): base(connectionString)
        {
        } 
        #endregion


        #region IBaseService<T> Members

        public virtual Result Create(T entity, Session session)
        {
            if (MakeInsert(entity, typeof(T), session))
            {
                return null;
            }

            return new Result("Failed to create entity");
        }

        public virtual Result Delete(T entity, Session session)
        {
            if (MakeDelete(entity, typeof(T), session))
            {
                return null;
            }
            return new Result("Unable to delete entity");
        }


        public virtual Result Update(T entity, Session session)
        {
            switch (entity.EntityState)
            {
                case EntityState.Created:
                    return Create(entity, session);

                case EntityState.Deleted:
                    return Delete(entity, session);

                case EntityState.Changed:
                    {
                        MakeUpdate(entity, typeof(T), session);
                        return null;
                    }
            }

            return null;
        }

        public virtual Result Update(ref EntityCollection<T> collection,  Session session)
        {
            if (MakeUpdate(collection, session))
                return null;
            else
                return new Result("Cannot update collection of entities");
        }

        /*
        public Sio.Mdm.Entities.Filter<T> Filter()
        {
            return new Filter<T>();
        }
         */

        public Result Select(ref EntityCollection<T> result, ISioFilter<T> filter, Session session)
        {
            result = MakeSelect<T>(filter, session, false);
            return null;
        }

        /// <summary>
        /// Select all deleted records. Select statement is build by Deleted field name.
        /// </summary>
        /// <param name="result"></param>
        /// <param name="filter"></param>
        /// <param name="session"></param>
        /// <returns></returns>
        public Result SelectDeleted(ref EntityCollection<T> result, ISioFilter<T> filter, Session session)
        {
            result = MakeSelect<T>(filter, session, true);
            return null;
        }


        public Result Count(ref int result, ISioFilter<T> filter, Session session)
        {
            result = MakeCount<T>(filter, session, false);
            return null;
        }

        public Result CountDeleted(ref int result, ISioFilter<T> filter, Session session)
        {
            result = MakeCount<T>(filter, session, true);
            return null;
        }

        #endregion
    }
}
